import $ from 'jquery';
import View from "./view";
import AssetsLoader from "./assets_loader";
import UrlUtil from "./url_util";
import Event from "./event";
import EventCenter from "./event_center";

class s {
  target = null;
  action = null;
  params = null;
  frame = NaN;
  constructor(e, t, n, r) {
    this.frame = e;
    this.target = r instanceof Object ? r : null;
    this.action = t;
    this.params = n instanceof Array ? n : [];
  }
}

export default class Movie extends View {
  className = "AXEMovie";
  dealloc() {
    let t = this;
    (t._frames = null), View.prototype.dealloc.call(t);
  }
  clone() {
    let e = this,
      t = new Movie();
    return e.copyProperties(t), t;
  }
  copyProperties(t) {
    let n = this;
    View.prototype.copyProperties.call(n, t),
      (t._frames = n.frames().slice()),
      t.pauseWhenAnimating(n.pauseWhenAnimating()),
      t.frameRate(n.frameRate()),
      t.loop(n.loop()),
      t.backToFirst(n.backToFirst());
    if (n.actions() != null) {
      t._actions = {};
      let r = n.actions();
      for (let i in r) r.hasOwnProperty(i) && (t._actions[i] = r[i]);
    }
  }
  updatePropsFromXML(r) {
    let i = this;
    View.prototype.updatePropsFromXML.call(i, r);
    let s = r.find("> frame"),
      o = i.frames();
    s.each(function (e, r) {
      let i = $(r),
        s = i.is("[repeat]") ? parseInt(i.attr("repeat"), 10) : 1;
      for (let u = 0; u < s; u++) {
        let a = i.text(),
          f = UrlUtil.splitURLs(a);
        i.is("[reverse]") && (f = f.reverse());
        for (let l = 0; l < f.length; l++) {
          let c = f[l];
          o.push(AssetsLoader.asset(c));
        }
      }
    }),
      r.is("[pause-when-animating]") &&
        i.pauseWhenAnimating(r.attr("pause-when-animating") === "true"),
      r.is("[fps]") && i.frameRate(parseFloat(r.attr("fps"))),
      i.loop(
        r.is("[loop]") ? String(r.attr("loop")).toLowerCase() == "true" : !0
      ),
      i.backToFirst(
        r.is("[back]") ? String(r.attr("back")).toLowerCase() == "true" : !1
      );
    let u = r.find("> script");
    u.each(function (e, t) {
      let n = $(t),
        r = n.attr("frame").toLowerCase(),
        s;
      r == "first"
        ? (s = 0)
        : r == "last"
        ? (s = i.framesCount() - 1)
        : (s = parseInt(r, 10));
      if (isNaN(s)) return;
      let o = n.attr("action"),
        u = o.split(":"),
        a = u[0],
        f = i[a];
      if (typeof f != "function") return;
      let l = [];
      if (u.length > 1) {
        l = u[1].split(",");
        for (let c = 0; c < l.length; c++) {
          let h = parseFloat(l[c]);
          if (isNaN(h) === !1) l[c] = h;
          else if (l[c] == "true" || l[c] == "false") l[c] = l[c] == "true";
        }
      }
      i.addAction(s, f, l, i);
    });
    let a = r.is("[auto-play]")
      ? String(r.attr("auto-play")).toLowerCase() == "true"
      : !0;
    a ? i.goToAndPlay(0) : i.goToAndStop(0);
  }
  _actions = null;
  actions() {
    let e = this;
    return e._actions == null && (e._actions = {}), e._actions;
  }
  frameActions(e) {
    let t = this,
      n = String(e),
      r = null;
    return t.actions().hasOwnProperty(n) && (r = t.actions()[n]), r;
  }
  addAction(e, t, n, r) {
    let i = this,
      o = new s(e, t, n, r),
      u = i.frameActions(e);
    return u == null && ((u = []), (i.actions()[String(e)] = u)), u.push(o), o;
  }
  removeAction(e) {
    let t = this,
      n = t.frameActions(e.frame);
    if (n != null)
      for (let r = 0; r < n.length; r++)
        if (n[r] == e) {
          n.splice(r, 1);
          break;
        }
  }
  removeFrameAction(e) {
    let t = this,
      n = t.frameActions(e);
    n != null && delete t.actions()[String(e)];
  }
  _backToFirst = !1;
  backToFirst(e?) {
    let t = this;
    return arguments.length > 0 && (t._backToFirst = e), t._backToFirst;
  }
  _loop = !0;
  loop(e?) {
    let t = this;
    return arguments.length > 0 && (t._loop = e), t._loop;
  }
  _finishAction = null;
  duration() {
    let e = this;
    return e.framesCount() / e.frameRate();
  }
  framesCount() {
    let e = this;
    return e.frames().length;
  }
  addFramesByURL(e, r, i) {
    let s = this;
    (i = isNaN(i) ? 1 : i), (r = typeof r == "boolean" ? r : !1);
    let o = s.frames();
    for (let u = 0; u < i; u++) {
      let a = UrlUtil.splitURLs(e);
      r && (a = a.reverse());
      for (let f = 0; f < a.length; f++) {
        let l = a[f];
        o.push(AssetsLoader.asset(l));
      }
    }
  }
  _frames = null;
  frames(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        e != null &&
        ((t._frames = e.slice()), t.needToRender(!0)),
      t._frames == null && (t._frames = []),
      t._frames
    );
  }
  _frameRate = 24;
  frameRate(e?) {
    let t = this;
    return (
      isNaN(e) === !1 && ((t._frameRate = e), t.needToRender(!0)), t._frameRate
    );
  }
  reverse() {
    let e = this,
      t = e.frames();
    t.reverse(), e.frames(t);
  }
  playing = !1;
  play() {
    let e = this;
    if (e.playing) return;
    e.playing = !0;
  }
  stop() {
    let e = this;
    e.playing && (e.playing = !1);
  }
  goToAndStop(e) {
    let t = this;
    t.stop(),
      (t._currentFrame = Math.max(0, Math.min(t.framesCount() - 1, e))),
      t.needToRender(!0);
  }
  goToAndPlay(e) {
    let t = this;
    t.goToAndStop(e), t.play(), t.needToRender(!0);
  }
  _currentFrame = 0;
  currentFrame() {
    let e = this;
    return Math.floor(e._currentFrame);
  }
  _pauseWhenAnimating = !1;
  pauseWhenAnimating(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        e != t._pauseWhenAnimating &&
        (t._pauseWhenAnimating = e),
      t._pauseWhenAnimating
    );
  }
  update(t, n) {
    let s = this;
    View.prototype.update.call(s, t, n);
    if (s.playing && (s.pauseWhenAnimating() === !1 || s.animating() === !1)) {
      let o = n * s.frameRate(),
        u = Math.floor(s._currentFrame + o),
        a = s.currentFrame(),
        f = u - a,
        l = s._currentFrame + o - u;
      for (let c = 0; c < f; c++) {
        let h = s.currentFrame(),
          p = s.frameActions(h);
        if (p != null) for (let d = 0; d < p.length; d++) p[d].execute();
        (s._currentFrame = s.currentFrame() + 1),
          s._currentFrame == s.framesCount() &&
            (s.loop()
              ? (s._currentFrame = 0)
              : ((s._currentFrame = s.backToFirst() ? 0 : s.framesCount() - 1),
                s.stop()),
            EventCenter.dispatchEvent(new Event(s, Event.END))),
          s.needToRender(!0),
          EventCenter.dispatchEvent(new Event(s, Event.CHANGE));
        if (s.playing == 0) break;
      }
      s.playing && (s._currentFrame = s.currentFrame() + l);
    }
  }
}
